﻿//#define Debug

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.ModFlow.Domain.DomainLayer;

using HAUtil;
using DotSpatial.Topology;
using DotSpatial.Data;
using System.Diagnostics;



namespace HA.Data
{
    [Serializable]
    public class Coverage : CoverageBase
    {
        public Coverage(LAYERCOVERAGETYPE type)
        {
            this._coverageType = type;
            this._setup = new CoverageSetup();
            this._featureobjects = new List<FeatureObject>();
            this._assistData = new AssistDataForCoverage();
        }

        public Coverage(LAYERCOVERAGETYPE type,CoverageSetup setup)
        {
            this._coverageType = type;
            this._setup = setup;
            this._featureobjects = new List<FeatureObject>();
            this._assistData = new AssistDataForCoverage();
        }

        public Coverage(Coverage coverage)
        {
            this._coverageType = coverage.CoverageType;
            this._setup = (CoverageSetup)coverage.Setup.Clone();

            this._featureobjects = new List<FeatureObject>();

            foreach (FeatureObject item in coverage.Featureobjects)
            {
                FeatureObject copy = (FeatureObject)item.Clone();

                copy.Parent = this;

                this._featureobjects.Add(copy);

            }



            //清除原有线面关系，复原原有线点关系
            foreach (FeatureObject item in this._featureobjects)
            {
                if (item is NodeFO)
                {
                    NodeFO nf = (NodeFO)item;

                    for (int i = 0; i < nf.RelationLines.Count; i++)
                    {
                        nf.RelationLines[i] = (LineFO)_featureobjects.Find(h => h.Id == nf.RelationLines[i].Id);
                    }
                }
                if (item is LineFO)
                {
                    LineFO lf = (LineFO)item;

                    lf.VertexStart.Node = (NodeFO)_featureobjects.Find(h => h.Id == lf.VertexStart.Id);
                    lf.VertexEnd.Node = (NodeFO)_featureobjects.Find(h => h.Id == lf.VertexEnd.Id);

                    for (int i = 0; i < lf.RelatedPolygonFO.Count; i++)
                    {
                        lf.RelatedPolygonFO[i] = (PolygonFO)_featureobjects.Find(h => h.Id == lf.RelatedPolygonFO[i].Id);
                    }
                }
                else if (item is PolygonFO)
                {
                    PolygonFO pf = (PolygonFO)item;

                    for (int i = 0; i < pf.RelationLines.Count; i++)
                    {
                        pf.RelationLines[i] = new LineAndDirection((LineFO)_featureobjects.Find(h => h.Id == pf.RelationLines[i].Line.Id), pf.RelationLines[i].Direction);
                    }

                    for (int j = 0; j < pf.HoleRelationLines.Count; j++)
                    {
                        List<LineAndDirection> rings = pf.HoleRelationLines[j];

                        for (int i = 0; i < rings.Count; i++)
                        {
                            rings[i] = new LineAndDirection((LineFO)_featureobjects.Find(h => h.Id == rings[i].Line.Id), rings[i].Direction);
                        }
                    }
                }
            }


            this.Name = coverage.Name + "Copy";
            this._assistData =(AssistDataForCoverage) coverage._assistData.Clone();

        }

        #region New

        bool[] _checkedGeoParam = new bool[4];
        /// <summary>
        /// Index 0—层海拔，1-LPF/BCF,2-UZF参数，3-溶质运移模型
        /// </summary>
        public bool[] CheckedGeoParam
        {
            get { return _checkedGeoParam; }
        }


        LAYERCOVERAGETYPE _coverageType;

        public LAYERCOVERAGETYPE CoverageType
        {
            get { return _coverageType; }
        }

        public List<FeatureObject> GetFeatureObjectClone()
        {
            List<FeatureObject> foes = new List<FeatureObject>();

            foreach (FeatureObject item in this.Featureobjects)
            {
                FeatureObject copy = (FeatureObject)item.Clone();

                foes.Add(copy);

            }



            //清除原有线面关系，复原原有线点关系
            foreach (FeatureObject item in foes)
            {
                if (item is NodeFO)
                {
                    NodeFO nf = (NodeFO)item;

                    for (int i = 0; i < nf.RelationLines.Count; i++)
                    {
                        nf.RelationLines[i] = (LineFO)foes.Find(h => h.Id == nf.RelationLines[i].Id);
                    }
                }
                if (item is LineFO)
                {
                    LineFO lf = (LineFO)item;

                    lf.VertexStart.Node = (NodeFO)foes.Find(h => h.Id == lf.VertexStart.Id);
                    lf.VertexEnd.Node = (NodeFO)foes.Find(h => h.Id == lf.VertexEnd.Id);

                    for (int i = 0; i < lf.RelatedPolygonFO.Count; i++)
                    {
                        lf.RelatedPolygonFO[i] = (PolygonFO)foes.Find(h => h.Id == lf.RelatedPolygonFO[i].Id);
                    }
                }
                else if (item is PolygonFO)
                {
                    PolygonFO pf = (PolygonFO)item;

                    for (int i = 0; i < pf.RelationLines.Count; i++)
                    {
                        //句柄错误！。。。。。。应整个换掉。。。。。。 终于找到你了。。。
                        //pf.RelationLines[i].Line = (LineFO)foes.Find(h => h.Id == pf.RelationLines[i].Line.Id);
                        pf.RelationLines[i] = new LineAndDirection((LineFO)foes.Find(h => h.Id == pf.RelationLines[i].Line.Id), pf.RelationLines[i].Direction);
                    }

                    for (int j = 0; j < pf.HoleRelationLines.Count; j++)
                    {
                        List<LineAndDirection> rings = pf.HoleRelationLines[j];

                        for (int i = 0; i < rings.Count; i++)
                        {
                            //rings[i].Line = (LineFO)foes.Find(h => h.Id == rings[i].Line.Id);
                            rings[i] = new LineAndDirection((LineFO)foes.Find(h => h.Id == rings[i].Line.Id), rings[i].Direction);
                        }
                    }
                }
            }

            return foes;
        }

        public void Add(LineFO lineFO)
        {
            List<FeatureObject> foes = new List<FeatureObject>();
            foes.Add(lineFO);

            lineFO.LayerRange.FromLayer = this._setup.LayerStart;
            lineFO.LayerRange.ToLayer = this._setup.LayerEnd;

            NodeFO nodeFO = null;
            if ((nodeFO = (NodeFO)this._featureobjects.FirstOrDefault(h => h.Id == lineFO.VertexStart.Id)) != null)
            {
                if (!nodeFO.RelationLines.Contains(lineFO))
                    nodeFO.RelationLines.Add(lineFO);
            }
            else
            {
                this._featureobjects.Add(lineFO.VertexStart.Node);

                foes.Add(lineFO.VertexStart.Node);

                if (!lineFO.VertexStart.Node.RelationLines.Contains(lineFO))
                    lineFO.VertexStart.Node.RelationLines.Add(lineFO);
            }

            if ((nodeFO = (NodeFO)this._featureobjects.FirstOrDefault(h => h.Id == lineFO.VertexEnd.Id)) != null)
            {
                if (!nodeFO.RelationLines.Contains(lineFO))
                    nodeFO.RelationLines.Add(lineFO);
            }
            else
            {
                this._featureobjects.Add(lineFO.VertexEnd.Node);

                foes.Add(lineFO.VertexEnd.Node);

                if (!lineFO.VertexEnd.Node.RelationLines.Contains(lineFO))
                    lineFO.VertexEnd.Node.RelationLines.Add(lineFO);
            }

            this._featureobjects.Add(lineFO);

            if (this._parentCM != null)
            {
                if (this._parentCM.ParentMapData != null)
                {
                    this.ParentCM.ParentMapData.AskFOCollecionChanged(new FOCollecionChangedEventArgs(this.ParentCM, this, foes, CollectionChangedType.ADD));
                }
            }
        }

        double ComputeLineTotalAngle(List<HCoordinate> coords)
        {
            double angle = 0;

            HCoordinate start;
            HCoordinate end;
            double agl1 = 0;
            double agl2=0;

            for (int i = 1; i < coords.Count - 1; i++)
            {
                start = coords[i - 1] - coords[i];
                end = coords[i + 1] - coords[i];

                agl1 = start.X < 0 ? Math.Asin((-start.Y) / (Math.Sqrt(start.X * start.X + start.Y * start.Y))) : Math.Asin(start.Y / (Math.Sqrt(start.X * start.X + start.Y * start.Y)));
                if (start.X < 0 && start.Y >= 0)
                    agl1 += Math.PI;
                else if (start.X < 0 && start.Y < 0)
                    agl1 -= Math.PI;

                agl2 = end.X < 0 ? Math.Asin((-end.Y) / (Math.Sqrt(end.X * end.X + end.Y * end.Y))) : Math.Asin(end.Y / (Math.Sqrt(end.X * end.X + end.Y * end.Y)));
                if (end.X < 0 && end.Y >= 0)
                    agl2 += Math.PI;
                else if (end.X < 0 && end.Y < 0)
                    agl2 -= Math.PI;

                angle += (agl2 - agl1 + Math.PI * 2.0) % (Math.PI * 2.0);
            }

            return angle;
        }

        //新构造多边形算法相关

        /// <summary>
        /// 去除枝干,计算角度
        /// </summary>
        /// <param name="polygonFOes">生成的多边形集合</param>
        /// <returns></returns>
        bool CutBranchesComputePolyRings(ref List<PolygonFO> polygonFOes)
        {
            //取副本伪实现
            //待测试重取   占位
            List<FeatureObject> featureOb = this._featureobjects.CloneList();
            List<FeatureObject> sourceLines = _featureobjects.FindAll(h => h.GetType() == typeof(LineFO));

            //进行操作的线 操作时会变化
            List<FeatureObject> lines = featureOb.FindAll(h => h.GetType() == typeof(LineFO));
            //进行操作的点 操作时会变化
            List<FeatureObject> nodes = featureOb.FindAll(h => h.GetType() == typeof(NodeFO));

            //关系更新
            for (int i = 0; i < lines.Count; i++)
            {
                (lines[i] as LineFO).VertexStart.Node = (NodeFO)nodes.First<FeatureObject>(h => h.Id == (lines[i] as LineFO).VertexStart.Id);
                (lines[i] as LineFO).VertexEnd.Node = (NodeFO)nodes.First<FeatureObject>(h => h.Id == (lines[i] as LineFO).VertexEnd.Id);
            }
            for (int i = 0; i < nodes.Count; i++)
            {
                int count = (nodes[i] as NodeFO).RelationLines.Count;
                NodeFO nf = (NodeFO)this._featureobjects.First<FeatureObject>(h => h.Id == nodes[i].Id);
                (nodes[i] as NodeFO).RelationLines = new List<LineFO>();
                for (int j = 0; j < count; j++)
                {
                    (nodes[i] as NodeFO).RelationLines.Add((LineFO)lines.First<FeatureObject>(h => h.Id == nf.RelationLines[j].Id));
                }
            }



            //操作过程中存储只与一条线相关联的点集合
            List<FeatureObject> oneLineRelationNodes;

            if (lines.Count < 1 || nodes.Count < 1)
                return false;

            //首尾点相同的环可直接生成多边形
            List<FeatureObject> OneVertexRing = new List<FeatureObject>();

            //取出所有单点多边形，顺便索引
            foreach (LineFO item in lines)
            {
                if (item.VertexStart.Id == item.VertexEnd.Id && item.Coords != null && item.Coords.Count > 0)
                {
                    OneVertexRing.Add(item);
                    List<HCoordinate> coords = item.ToCoordinatesArray();
                    coords.RemoveAt(coords.Count - 1);
                    polygonFOes.Add(new PolygonFO(this.GetNextPolygonId(), new List<LineAndDirection>() { new LineAndDirection((LineFO)sourceLines.First<FeatureObject>(h => h.Id == item.Id)) }, new List<List<LineAndDirection>>(), this));
                }
            }

            //从lines中删除并更新相应端点信息
            foreach (LineFO ring in OneVertexRing)
            {
                LineFO line = (LineFO)lines.First<FeatureObject>(h => h.Id == ring.Id);
                if (line.VertexStart.Node.RelationLines.Contains(line))
                    line.VertexStart.Node.RelationLines.Remove(line);
                lines.Remove(ring);
            }

            //去除枝干
            while ((oneLineRelationNodes = nodes.FindAll(h => ((NodeFO)h).RelationLines.Count <= 1)).Count != 0) 
            {
                foreach (NodeFO item in oneLineRelationNodes)
                {
                    if (item.RelationLines.Count == 0)
                    {
                        nodes.Remove(item);
                        continue;
                    }
                    if (item.RelationLines[0].VertexStart.Id == item.Id)
                    {
                        item.RelationLines[0].VertexEnd.Node.RelationLines.Remove(item.RelationLines[0]);
                    }
                    else if (item.RelationLines[0].VertexEnd.Id == item.Id)
                    {
                        item.RelationLines[0].VertexStart.Node.RelationLines.Remove(item.RelationLines[0]);
                    }
                    else
                    {
                        throw new Exception("线点信息存储错误！");
                    }

                    lines.Remove(lines.First<FeatureObject>(h=>h.Id==item.RelationLines[0].Id) );

                    nodes.Remove(item);
                }
            }

            //计算各线弧度
            HCoordinate helpCoord=new HCoordinate();
            foreach (LineFO item in lines)
            {
                if (item.Coords != null && item.Coords.Count > 0)
                {
                    helpCoord.X = item.Coords[0].X - item.VertexStart.Node.Position.X;
                    helpCoord.Y = item.Coords[0].Y - item.VertexStart.Node.Position.Y;

                    item.VertexStart.Angle = helpCoord.X < 0 ? Math.Asin((-helpCoord.Y) / (Math.Sqrt(helpCoord.X * helpCoord.X + helpCoord.Y * helpCoord.Y))) : Math.Asin(helpCoord.Y / (Math.Sqrt(helpCoord.X * helpCoord.X + helpCoord.Y * helpCoord.Y)));
                    if (helpCoord.X < 0 && helpCoord.Y >= 0)
                        item.VertexStart.Angle += Math.PI;
                    else if (helpCoord.X < 0 && helpCoord.Y < 0)
                        item.VertexStart.Angle -= Math.PI;

                    helpCoord.X = item.Coords[item.Coords.Count - 1].X - item.VertexEnd.Node.Position.X;
                    helpCoord.Y = item.Coords[item.Coords.Count - 1].Y - item.VertexEnd.Node.Position.Y;
                    item.VertexEnd.Angle = helpCoord.X < 0 ? Math.Asin((-helpCoord.Y) / (Math.Sqrt(helpCoord.X * helpCoord.X + helpCoord.Y * helpCoord.Y))) : Math.Asin(helpCoord.Y / (Math.Sqrt(helpCoord.X * helpCoord.X + helpCoord.Y * helpCoord.Y)));

                    if (helpCoord.X < 0 && helpCoord.Y >= 0)
                        item.VertexEnd.Angle += Math.PI;
                    else if (helpCoord.X < 0 && helpCoord.Y < 0)
                        item.VertexEnd.Angle -= Math.PI;

                    item.InnerLineAngle = ComputeLineTotalAngle(item.ToCoordinatesArray());
                }
                else
                {
                    helpCoord.X = item.VertexEnd.Node.Position.X - item.VertexStart.Node.Position.X;
                    helpCoord.Y = item.VertexEnd.Node.Position.Y - item.VertexStart.Node.Position.Y;
                    item.VertexStart.Angle = helpCoord.X < 0 ? Math.Asin((-helpCoord.Y) / (Math.Sqrt(helpCoord.X * helpCoord.X + helpCoord.Y * helpCoord.Y))) : Math.Asin(helpCoord.Y / (Math.Sqrt(helpCoord.X * helpCoord.X + helpCoord.Y * helpCoord.Y)));
                    if (helpCoord.X < 0 && helpCoord.Y >= 0)
                        item.VertexStart.Angle += Math.PI;
                    else if (helpCoord.X < 0 && helpCoord.Y < 0)
                        item.VertexStart.Angle -= Math.PI;

                    if (item.VertexStart.Angle >= 0)
                        item.VertexEnd.Angle = item.VertexStart.Angle - Math.PI;
                    else
                        item.VertexEnd.Angle = item.VertexStart.Angle + Math.PI;

                    item.InnerLineAngle = 0;
                }
            }

            //生成多边形外框
            List<LineAndDirection> polygonOutlines;
            double TotalAngles;
            foreach (LineFO item in lines)
            {
                item.CurrentDirection = 1;
                item.SearchTime = 0;
            }
            NodeFO startNode;
            NodeFO currentNode;
            LineFO currentLine;
            foreach (LineFO item in lines)
            {
                int searchTimeNeedDecrease = 0;
                while (item.SearchTime < 2)
                {
                    #if Debug
                    {
                        foreach (LineFO l in lines)
                        {
                            Debug.WriteLine(l.Id+ "的遍历次数为："+l.SearchTime);
                        }

                        Debug.WriteLine("===============================");
                    }
                    #endif


                    bool isAdd = true;

                    polygonOutlines = new List<LineAndDirection>();
                    TotalAngles = 0;

                    if (item.SearchTime == 0)
                    {
                        startNode = item.VertexStart.Node;
                        currentNode = item.VertexEnd.Node;
                        currentLine = item;
                        currentLine.SearchTime++;
                        polygonOutlines.Add(new LineAndDirection((LineFO)sourceLines.First<FeatureObject>(h => h.Id == currentLine.Id), 1));
                        //TotalAngles += (currentLine.VertexStart.Angle - currentLine.VertexEnd.Angle + Math.PI * 2.0) % (Math.PI * 2.0);
                        TotalAngles += currentLine.CurrentDirection == 1 ? currentLine.InnerLineAngle : (currentLine.Coords.Count * Math.PI * 2.0 - currentLine.InnerLineAngle);

                        while (startNode.Id != currentNode.Id)
                        {
                            double minAngle = 10;
                            LineFO minAngleLine = null;
                            double currentAngle;
                            bool isDirection1 = true;
                            foreach (LineFO line in currentNode.RelationLines)
                            {
                                if (polygonOutlines.FirstOrDefault<LineAndDirection>(h => h.Line.Id == line.Id) != null)
                                    continue;

                                if (line.VertexStart.Id == currentNode.Id)
                                {
                                    currentAngle = (line.VertexStart.Angle - (currentLine.CurrentDirection == 1 ? currentLine.VertexEnd.Angle : currentLine.VertexStart.Angle) + Math.PI * 2) % (Math.PI * 2);
                                    //if (currentAngle == 0) continue;
                                    if (currentAngle < minAngle)
                                    {
                                        minAngle = currentAngle;
                                        minAngleLine = line;
                                        isDirection1 = true;
                                    }
                                }
                                else if (line.VertexEnd.Id == currentNode.Id)
                                {
                                    currentAngle = (line.VertexEnd.Angle - (currentLine.CurrentDirection == 1 ? currentLine.VertexEnd.Angle : currentLine.VertexStart.Angle) + Math.PI * 2) % (Math.PI * 2);
                                    //if (currentAngle == 0) continue;
                                    if (currentAngle < minAngle)
                                    {
                                        minAngle = currentAngle;
                                        minAngleLine = line;
                                        isDirection1 = false;
                                    }
                                }
                                else
                                    throw new Exception();
                            }
                            if (minAngleLine == null)
                            {
                                isAdd = false;
                                for (int i = 1; i < polygonOutlines.Count; i++)
                                {
                                    searchTimeNeedDecrease++;
                                    polygonOutlines[i].Line.SearchTime--;
                                }
                                break;
                            }
                            currentLine = minAngleLine;
                            if (isDirection1)
                            {
                                currentLine.CurrentDirection = 1;
                                currentNode = currentLine.VertexEnd.Node;
                                //minAngle += (currentLine.VertexStart.Angle - currentLine.VertexEnd.Angle + Math.PI * 2.0) % (Math.PI * 2.0);
                                minAngle += currentLine.InnerLineAngle;
                            }
                            else
                            {
                                currentLine.CurrentDirection = -1;
                                currentNode = currentLine.VertexStart.Node;
                                //minAngle += (currentLine.VertexEnd.Angle - currentLine.VertexStart.Angle + Math.PI * 2.0) % (Math.PI * 2.0);
                                minAngle += currentLine.Coords.Count * Math.PI * 2.0 - currentLine.InnerLineAngle;
                            }
                            TotalAngles += minAngle;
                            if (currentLine.SearchTime > 1)
                            {
                                isAdd = false;
                                for (int i = 1; i < polygonOutlines.Count; i++)
                                {
                                    searchTimeNeedDecrease++;
                                    polygonOutlines[i].Line.SearchTime--;
                                }
                                break;
                            }
                            currentLine.SearchTime++;

                            polygonOutlines.Add(new LineAndDirection((LineFO)sourceLines.First<FeatureObject>(h => h.Id == currentLine.Id), currentLine.CurrentDirection));
                        }

                        if (item.VertexStart.Id == startNode.Id)
                        {
                            TotalAngles += (item.VertexStart.Angle - (currentLine.CurrentDirection == 1 ? currentLine.VertexEnd.Angle : currentLine.VertexStart.Angle) + Math.PI * 2) % (Math.PI * 2);
                        }
                        else
                        {
                            TotalAngles += (item.VertexEnd.Angle - (currentLine.CurrentDirection == 1 ? currentLine.VertexEnd.Angle : currentLine.VertexStart.Angle) + Math.PI * 2) % (Math.PI * 2);
                        }


                    }
                    else if (item.SearchTime == 1)
                    {
                        item.CurrentDirection *= -1;
                        currentLine = item;

                        if (item.CurrentDirection == 1)
                        {
                            startNode = item.VertexStart.Node;
                            currentNode = item.VertexEnd.Node;
                            //TotalAngles += (currentLine.VertexStart.Angle - currentLine.VertexEnd.Angle + Math.PI * 2.0) % (Math.PI * 2.0);
                            TotalAngles += currentLine.InnerLineAngle;
                        }
                        else
                        {
                            startNode = item.VertexEnd.Node;
                            currentNode = item.VertexStart.Node;
                            //TotalAngles += (currentLine.VertexEnd.Angle - currentLine.VertexStart.Angle + Math.PI * 2.0) % (Math.PI * 2.0);
                            TotalAngles += currentLine.Coords.Count * Math.PI * 2.0 - currentLine.InnerLineAngle;
                        }


                        currentLine.SearchTime++;
                        polygonOutlines.Add(new LineAndDirection((LineFO)sourceLines.First<FeatureObject>(h => h.Id == currentLine.Id), currentLine.CurrentDirection));

                        while (startNode.Id != currentNode.Id)
                        {
                            double minAngle = 10;
                            LineFO minAngleLine = null;
                            double currentAngle;
                            bool isDirection1 = true;
                            foreach (LineFO line in currentNode.RelationLines)
                            {
                                if (polygonOutlines.FirstOrDefault<LineAndDirection>(h => h.Line.Id == line.Id) != null)
                                    continue;

                                if (line.VertexStart.Id == currentNode.Id)
                                {
                                    currentAngle = (line.VertexStart.Angle - (currentLine.CurrentDirection == 1 ? currentLine.VertexEnd.Angle : currentLine.VertexStart.Angle) + Math.PI * 2) % (Math.PI * 2);
                                    //if (currentAngle == 0) continue;
                                    if (currentAngle < minAngle)
                                    {
                                        minAngle = currentAngle;
                                        minAngleLine = line;
                                        isDirection1 = true;
                                    }
                                }
                                else if (line.VertexEnd.Id == currentNode.Id)
                                {
                                    currentAngle = (line.VertexEnd.Angle - (currentLine.CurrentDirection == 1 ? currentLine.VertexEnd.Angle : currentLine.VertexStart.Angle) + Math.PI * 2) % (Math.PI * 2);
                                    //if (currentAngle == 0) continue;
                                    if (currentAngle < minAngle)
                                    {
                                        minAngle = currentAngle;
                                        minAngleLine = line;
                                        isDirection1 = false;
                                    }
                                }
                                else
                                    throw new Exception();
                            }
                            if (minAngleLine == null)
                            {
                                isAdd = false;
                                for (int i = 1; i < polygonOutlines.Count; i++)
                                {
                                    searchTimeNeedDecrease++;
                                    polygonOutlines[i].Line.SearchTime--;
                                }
                                break;
                            }

                            currentLine = minAngleLine;
                            if (isDirection1)
                            {
                                currentLine.CurrentDirection = 1;
                                currentNode = currentLine.VertexEnd.Node;
                                //minAngle += (currentLine.VertexStart.Angle - currentLine.VertexEnd.Angle + Math.PI * 2.0) % (Math.PI * 2.0);
                                minAngle += currentLine.InnerLineAngle;
                            }
                            else
                            {
                                currentLine.CurrentDirection = -1;
                                currentNode = currentLine.VertexStart.Node;
                                //minAngle += (currentLine.VertexEnd.Angle - currentLine.VertexStart.Angle + Math.PI * 2.0) % (Math.PI * 2.0);
                                minAngle += currentLine.Coords.Count * Math.PI * 2.0 - currentLine.InnerLineAngle;
                            }
                            TotalAngles += minAngle;
                            if (currentLine.SearchTime > 1)
                            {
                                isAdd = false;
                                for (int i = 1; i < polygonOutlines.Count; i++)
                                {
                                    searchTimeNeedDecrease++;
                                    polygonOutlines[i].Line.SearchTime--;
                                }
                                break;
                            }
                            currentLine.SearchTime++;


                            polygonOutlines.Add(new LineAndDirection((LineFO)sourceLines.First<FeatureObject>(h => h.Id == currentLine.Id), currentLine.CurrentDirection));
                        }//while

                        if (item.VertexStart.Id == startNode.Id)
                        {
                            TotalAngles += (item.VertexStart.Angle - (currentLine.CurrentDirection == 1 ? currentLine.VertexEnd.Angle : currentLine.VertexStart.Angle) + Math.PI * 2) % (Math.PI * 2);
                        }
                        else
                        {
                            TotalAngles += (item.VertexEnd.Angle - (currentLine.CurrentDirection == 1 ? currentLine.VertexEnd.Angle : currentLine.VertexStart.Angle) + Math.PI * 2) % (Math.PI * 2);
                        }
                    }
                    else
                        continue;
                    if (isAdd)
                    {
                        #if Debug
                        foreach (var p in polygonOutlines)
                        {
                            Debug.Write("  "+p.Line.Id+" ");
                        }
                        Debug.WriteLine("");

                        #endif

                        int segmentCount = 0;

                        for (int i = 0; i < polygonOutlines.Count; i++)
                        {
                            segmentCount += polygonOutlines[i].Line.Coords.Count + 1;
                        }

                        if (Math.Abs(TotalAngles - (segmentCount - 2) * Math.PI) > 0.5)
                        {
                            for (int i = 1; i < polygonOutlines.Count; i++)
                            {
                                polygonOutlines[i].Line.SearchTime--;
                            }
                            continue;
                        }

                        polygonFOes.Add(new PolygonFO(this.GetNextPolygonId(), polygonOutlines, null, this));
                    }
                }//while

                item.SearchTime -= searchTimeNeedDecrease;

            }//foreach

            return true;
        }

        /// <summary>
        /// 新的构建多边形方法
        /// </summary>
        /// <returns></returns>
        public bool BuildPolygons()
        {
            List<PolygonFO> outRingPolyFoes = new List<PolygonFO>();

            if (!this.CutBranchesComputePolyRings(ref outRingPolyFoes))
                return false;

            this.NewBuildPolygon(ref outRingPolyFoes);

            return true;
        }

        /// <summary>
        /// 新的 根据多边形线，创建对应的多边形面，需要考虑相交的状况，基本思想就是平面分配，考虑中间扣洞的影响，还有就是不要出现重复的图形
        /// </summary>
        void NewBuildPolygon(ref List<PolygonFO> polyFoes)
        {
            //========================================保写=======================================
            //转换功能本在Gis中添加 现移植到主存储类中
            List<LineFO> lineFOes = new List<LineFO>();

            //string为id
            Dictionary<Polygon, string> polygons = new Dictionary<Polygon, string>();


            foreach (PolygonFO item in polyFoes)
            {
                Geometry geom = FetureObjectToGeometry(item);
                if (geom != null)
                {
                    polygons.Add(geom as Polygon, item.Id);
                }
            }

            ///生成所有外环多边形 数量跟最终生成的多边形一致 outerRingPolygons生成完毕后不会被更改
            int count = 0;
            Dictionary<int, PolygonRelates> polygonsWithRelates = new Dictionary<int, PolygonRelates>();
            foreach (Polygon item in polygons.Keys)
            {
                bool isBothContain = false;
                foreach (PolygonRelates value in polygonsWithRelates.Values)
                {
                    if (value.PolygonNoHole.Contains(item) && item.Contains(value.PolygonNoHole))
                    {
                        isBothContain = true;
                    }
                }

                if (!isBothContain)
                {
                    polygonsWithRelates.Add(count, new PolygonRelates(new Polygon(item.ExteriorRing.Coordinates),polygons[item]));
                    count++;
                }
            }



            //最终多边形  总的
            List<PolygonFO> finalPolyFO = new List<PolygonFO>();

            #region 开始生成
            List<int> usedIndex = new List<int>();
            foreach (int counter in polygonsWithRelates.Keys)
            {
                if (usedIndex.Contains(counter))
                    continue;

                CreatePolygonRelate(counter, ref polygonsWithRelates, ref usedIndex);
            }


            List<LineAndDirection> outerRelation;
            List<List<LineAndDirection>> holeRelations;
            //构建出新的POLYGONFO
            foreach (PolygonRelates forBuildPolygon in polygonsWithRelates.Values)
            {
                
                outerRelation = polyFoes.Find(h => h.Id == forBuildPolygon.PolygonId).RelationLines;

                holeRelations = new List<List<LineAndDirection>>();
                foreach (int containedPolygonIndex in forBuildPolygon.ContainPolygonIndex)
                {
                    holeRelations.Add(polyFoes.Find(h => h.Id == polygonsWithRelates[containedPolygonIndex].PolygonId).RelationLines);
                }

                PolygonFO newPolyFO = new PolygonFO(forBuildPolygon.PolygonId, outerRelation, holeRelations, this);
                newPolyFO.LayerRange.FromLayer = this._setup.LayerStart;
                newPolyFO.LayerRange.ToLayer = this._setup.LayerEnd;

                finalPolyFO.Add(newPolyFO);
            }


            //清除原有线面关系，复原原有线点关系
            foreach (FeatureObject item in this._featureobjects)
            {
                if (item is NodeFO)
                {
                    NodeFO nf = (NodeFO)item;

                    for (int i = 0; i < nf.RelationLines.Count; i++)
                    {
                        nf.RelationLines[i] = (LineFO)_featureobjects.Find(h => h.Id == nf.RelationLines[i].Id);
                    }
                }
                if (item is LineFO)
                {
                    LineFO lf = (LineFO)item;

                    lf.VertexStart.Node = (NodeFO)_featureobjects.Find(h => h.Id == lf.VertexStart.Id);
                    lf.VertexEnd.Node = (NodeFO)_featureobjects.Find(h => h.Id == lf.VertexEnd.Id);

                    lf.RelatedPolygonFO.Clear();
                }
            }

            //建立新的线关系
            foreach (PolygonFO polyFO in finalPolyFO)
            {
                foreach (LineAndDirection item in polyFO.RelationLines)
                {
                    item.Line.RelatedPolygonFO.Add(polyFO);
                }
                foreach (List<LineAndDirection> rings in polyFO.HoleRelationLines)
                {
                    foreach (LineAndDirection item in rings)
                    {
                        item.Line.RelatedPolygonFO.Add(polyFO);
                    }
                }
            }

            List<FeatureObject> finalFO = new List<FeatureObject>();
            //finalFO.AddRange(finalLineFO);
            //finalFO.AddRange(finalPointFO);
            finalFO.AddRange(this._featureobjects.FindAll(h => h.GetType() != typeof(PolygonFO)));
            finalFO.AddRange(finalPolyFO);

            this.ResetFO(finalFO);

            #endregion
        }


        #endregion



        #region 事件模型

        [field: NonSerialized]
        public event EventHandler<CollecionChangedEventArgs> CollecionChanged;


        [field: NonSerialized]
        public event EventHandler NameChanged;


        #endregion

        #region ID功能函数

        public string GetNextNodeId()
        {
            int index = this._assistData.NodeIndex;

            this._assistData.NodeIndex += 1;

            return "node" + index.ToString();

        }

        public string GetNextPointId()
        {
            int index = this._assistData.PtIndex;

            this._assistData.PtIndex += 1;

            return "point" + index.ToString();

        }

        public string GetNextLineId()
        {
            int index = this._assistData.LnIndex;

            this._assistData.LnIndex += 1;

            return "line" + index.ToString();

        }

        public string GetNextPolyLineId()
        {
            int index = this._assistData.PolylineIndex;

            this._assistData.PolylineIndex += 1;

            return "polyline" + index.ToString();

        }

        public string GetNextPolygonId()
        {
            int index = this._assistData.PolygonIndex;

            this._assistData.PolygonIndex += 1;

            return "polygon" + index.ToString();

        }



        #endregion

        ConceptualModel _parentCM;

        public ConceptualModel ParentCM
        {
            get { return _parentCM; }
            set { _parentCM = value; }
        }



        CoverageSetup _setup;


        /// <summary>
        /// 图层设置信息
        /// </summary>
        public CoverageSetup Setup
        {
            get { return _setup; }
            set
            {
                this._setup = value;
            }

        }





        List<FeatureObject> _featureobjects;

        public List<FeatureObject> Featureobjects
        {
            get { return _featureobjects; }

        }

        AssistDataForCoverage _assistData;


        #region 重写的方法


        protected override void OnsetName()
        {
            base.OnsetName();

            if (NameChanged != null)
            {
                NameChanged(this, new EventArgs());

            }


        }



        #endregion

        #region 公共函数

        ///// <summary>
        ///// 线转多边形
        ///// </summary>
        //private void LineToPolygon()
        //{
        //    //多边形线转多边形的时候还要考虑原本就存在的多边形
        //    //思路：每转换一个多边形，遍历所有已存在的多边形，判断相互关系，添加新的，修改原来的。图层刷新




        //    //查找所有的多边形线，再将所有的多边形线转换成多边形
        //    //foreach (IFeatureLayer layer in this.layerLst)
        //    //{
        //    //    if (layer.DataSet.FeatureType != FeatureType.Line) continue;

        //    //    foreach (IFeature feature in layer.DataSet.Features)
        //    //    {
        //    //        if (feature.BasicGeometry.Coordinates[0].X == feature.BasicGeometry.Coordinates[feature.BasicGeometry.Coordinates.Count - 1].X &&
        //    //            feature.BasicGeometry.Coordinates[0].Y == feature.BasicGeometry.Coordinates[feature.BasicGeometry.Coordinates.Count - 1].Y)
        //    //        {
        //    //            IFeature polygon = new Feature(FeatureType.Polygon, feature.BasicGeometry.Coordinates.CloneList());  // 是否要移除最后一个点呢，调试时再看
        //    //            polygons.Add(polygon);
        //    //        }
        //    //    }
        //    //}

        //    ////多边形判断相互关系
        //    //for (int i = 0; i < polygons.Count; i++)
        //    //{
        //    //    for (int j = 0; j < polygons.Count; j++)
        //    //    {
        //    //        if (i == j) continue;
        //    //        if (polygons[i].Contains(polygons[j]))
        //    //        {
        //    //            polygons[i] = polygons[i].Difference(polygons[j]);
        //    //        }
        //    //    }
        //    //}



        //}


        /// <summary>
        /// 将图层的有效范围映射为网格边界，待完成
        /// </summary>
        /// <returns></returns>
        public GridFrame GetCoverageFrame()
        {
            GridFrame gf = new GridFrame();

            double minX = double.MaxValue, minY = double.MaxValue, maxX = double.MinValue, maxY = double.MinValue;

            foreach (FeatureObject item in _featureobjects)
            {
                if (item is PointFO)
                {
                    PointFO pf = (PointFO)item;

                    minX = pf.Coords.X > minX ? minX : pf.Coords.X;
                    minY = pf.Coords.Y > minY ? minY : pf.Coords.Y;
                    maxX = pf.Coords.X < maxX ? maxX : pf.Coords.X;
                    maxY = pf.Coords.Y < maxY ? maxY : pf.Coords.Y;
                }
                else if (item is LineFO)
                {
                    LineFO lf = (LineFO)item;

                    foreach (HCoordinate coord in lf.ToCoordinatesArray())
                    {
                        minX = coord.X > minX ? minX : coord.X;
                        minY = coord.Y > minY ? minY : coord.Y;
                        maxX = coord.X < maxX ? maxX : coord.X;
                        maxY = coord.Y < maxY ? maxY : coord.Y;
                    }
                }
                else if(item is PolygonFO)
                {
                    PolygonFO plf = (PolygonFO)item;

                    foreach (HCoordinate coord in plf.Coords)
                    {
                        minX = coord.X > minX ? minX : coord.X;
                        minY = coord.Y > minY ? minY : coord.Y;
                        maxX = coord.X < maxX ? maxX : coord.X;
                        maxY = coord.Y < maxY ? maxY : coord.Y;
                    }
                }
            }

            if (minX <= maxX || minY <= maxY)
            {
                gf.XOrg = minX;
                gf.YOrg = minY;
                gf.ZOrg = this.Setup.DefaultElevation;

                gf.XLength = maxX - minX;
                gf.YLength = maxY - minY;
                
            }

            return gf;

        }


       


        /// <summary>
        /// Geometry转换FetureObject 适用闭合线及多边形 其他返回null ====保提供==== 
        /// </summary>
        /// <param name="geo"></param>
        /// <returns></returns>
        PolygonFO PolygonToFetureObject(Polygon polygon,string polylineKey)
        {
            //外环坐标
            List<HCoordinate> coords = new List<HCoordinate>();

            //洞坐标
            List<List<HCoordinate>> innerHoles = new List<List<HCoordinate>>();

            IList<Coordinate> coorLst = polygon.ExteriorRing.Coordinates;
            foreach (Coordinate item in coorLst)
            {
                coords.Add(new HCoordinate(item.X,item.Y));
            }
            coords.RemoveAt(coords.Count-1);
            
            
            foreach (ILinearRing linearRing in polygon.Holes)
            {
                List<HCoordinate> innerhole = new List<HCoordinate>();

                IList<Coordinate> lr = linearRing.Coordinates;
                foreach (Coordinate item in lr)
                {
                    innerhole.Add(new HCoordinate(item.X, item.Y));
                }
                innerhole.RemoveAt(innerhole.Count - 1);
                innerHoles.Add(innerhole);
            }

            return new PolygonFO(this.GetNextPolygonId(), polylineKey, coords, innerHoles,this);
        }

        /// <summary>
        /// FetureObject转换Geometry 适用闭合线及多边形 其他返回null ====保提供====
        /// </summary>
        /// <param name="fo"></param>
        /// <returns></returns>
        Geometry FetureObjectToGeometry(FeatureObject fo)
        {
            if (fo is PolygonFO)
            {
                List<LinearRing> innerLR = new List<LinearRing>();
                PolygonFO pyfo = fo as PolygonFO;
                List<Coordinate> exteriorRing = new List<Coordinate>();

                foreach (HCoordinate coord in pyfo.Coords)
                {
                    exteriorRing.Add(new Coordinate(coord.X, coord.Y));
                }

                List<Coordinate> hole;
                foreach (List<HCoordinate> innerhole in pyfo.InnerHoles)
                {
                    hole = new List<Coordinate>();
                    foreach (HCoordinate coord in innerhole)
                    {
                        hole.Add(new Coordinate(coord.X, coord.Y));
                    }
                    if (hole.Count >= 3)//首尾并非重合点  
                        innerLR.Add(new LinearRing(hole));
                }

                return new Polygon(new LinearRing(exteriorRing), innerLR.ToArray());

            }

            else if (fo is LineFO)
            {
                LineFO lfo = fo as LineFO;
                if (lfo.IsEnclosed)
                {
                    List<Coordinate> coords = new List<Coordinate>();

                    foreach (HCoordinate coord in lfo.ToCoordinatesArray())
                    {
                        coords.Add(new Coordinate(coord.X, coord.Y));
                    }
                    if (coords.Count >= 3)//首尾并非重合点  
                        return new LinearRing(coords);
                }
            }

            return null;
        }

        #region old

        ///// <summary>
        ///// 根据多边形线，创建对应的多边形面，需要考虑相交的状况，基本思想就是平面分配，考虑中间扣洞的影响，还有就是不要出现重复的图形
        ///// </summary>
        //public void BuildPolygonFO()
        //{
        //    Stopwatch sw = new Stopwatch();
        //    sw.Start();
        //    //========================================保写=======================================
        //    //转换功能本在Gis中添加 现移植到主存储类中
        //    List<LineFO> lineFOes = new List<LineFO>();
        //    List<PolygonFO> polyFoes = new List<PolygonFO>();

        //    List<LinearRing> lrs = new List<LinearRing>();

        //    //string为polylineKey
        //    Dictionary<Polygon, string> polygons = new Dictionary<Polygon,string>();

        //    //string为polylineKey
        //    Dictionary<Polygon, string> newAddPolygons = new Dictionary<Polygon, string>();

        //    //先取出所有多边形及 未转换过的多边形线
        //    foreach (FeatureObject fo in this._featureobjects)
        //    {
        //        if (fo is LineFO)
        //        {
        //            LineFO lfo = fo as LineFO;
        //            if (lfo.IsEnclosed && GetFetureObjectFormPolyline(lfo.PolyKey) == null)
        //            {
        //                lineFOes.Add(lfo);
        //            }
        //        }
        //        else if (fo is PolygonFO)
        //        {
        //            polyFoes.Add(fo as PolygonFO);
        //        }
        //    }

        //    //无需转换时返回
        //    //if (lineFOes.Count <= 0) return;


        //    //转换出相应Geometry
        //    foreach (LineFO item in lineFOes)
        //    {
        //        Geometry geom = FetureObjectToGeometry(item);
        //        if (geom != null)
        //        {
        //            lrs.Add(geom as LinearRing);
        //            newAddPolygons.Add(new Polygon(geom as LinearRing),item.PolyKey);
        //        }
        //    }
        //    foreach (PolygonFO item in polyFoes)
        //    {
        //        Geometry geom = FetureObjectToGeometry(item);
        //        if (geom != null)
        //        {
        //            polygons.Add(geom as Polygon,item.PolyKey);
        //        }
        //    }

        //    ///生成所有外环多边形 数量跟最终生成的多边形一致 outerRingPolygons生成完毕后不会被更改
        //    int count = 0;
        //    Dictionary<int, PolygonRelates> polygonsWithRelates = new Dictionary<int, PolygonRelates>();
        //    foreach (Polygon item in polygons.Keys)
        //    {
        //        bool isBothContain = false;
        //        foreach (PolygonRelates value in polygonsWithRelates.Values)
        //        {
        //            if (value.PolygonNoHole.Contains(item) && item.Contains(value.PolygonNoHole))
        //            {
        //                isBothContain = true;
        //            }
        //        }

        //        if (!isBothContain)
        //        {
        //            polygonsWithRelates.Add(count, new PolygonRelates(new Polygon(item.ExteriorRing.Coordinates), polygons[item]));
        //            count++;
        //        }
        //    }

        //    foreach (Polygon item in newAddPolygons.Keys)
        //    {
        //        bool isBothContain = false;
        //        foreach (PolygonRelates value in polygonsWithRelates.Values)
        //        {
        //            if (value.PolygonNoHole.Contains(item) && item.Contains(value.PolygonNoHole))
        //            {
        //                isBothContain = true;
        //            }
        //        }

        //        if (!isBothContain)
        //        {
        //            polygonsWithRelates.Add(count, new PolygonRelates(item, newAddPolygons[item]));
        //            count++;
        //        }
        //    }


        //    //最终多边形  总的
        //    Dictionary<Polygon, string> finalPolygons = new Dictionary<Polygon, string>();

        //    #region 开始生成
        //    List<int> usedIndex = new List<int>();
        //    foreach (int counter in polygonsWithRelates.Keys)
        //    {
        //        if (usedIndex.Contains(counter))
        //            continue;

        //        CreatePolygonRelate(counter, ref polygonsWithRelates, ref usedIndex);
        //    }

        //    foreach (PolygonRelates forBuildPolygon in polygonsWithRelates.Values)
        //    {
                
        //        LinearRing outerLR=new LinearRing(forBuildPolygon.PolygonNoHole.ExteriorRing.Coordinates);
        //        List<LinearRing> holes = new List<LinearRing>();
        //        foreach (int containedPolygonIndex in forBuildPolygon.ContainPolygonIndex)
        //        {
        //            holes.Add(new LinearRing(polygonsWithRelates[containedPolygonIndex].PolygonNoHole.ExteriorRing.Coordinates));
        //        }
        //        Polygon poly;
        //        if(holes.Count<=0)
        //            poly = new Polygon(outerLR);
        //        else
        //            poly=new Polygon(outerLR,holes.ToArray());


        //        finalPolygons.Add(poly,forBuildPolygon.PolygonId);
        //    }

        //    List<PolygonFO> finalPolyFO = new List<PolygonFO>();

        //    ///转换回polygonFO
        //    foreach (Polygon py in finalPolygons.Keys)
        //    {
        //        PolygonFO pfo = PolygonToFetureObject(py, finalPolygons[py]);



        //        if (pfo != null)
        //        {
        //            pfo.LayerRange.FromLayer = this.Setup.LayerStart;

        //            pfo.LayerRange.ToLayer = this.Setup.LayerEnd;


        //            finalPolyFO.Add(pfo);
        //        }
        //    }

        //    List<PointFO> finalPointFO = new List<PointFO>();
        //    List<LineFO> finalLineFO = new List<LineFO>();
        //    foreach (FeatureObject item in this._featureobjects)
        //    {
        //        if (item is PointFO)
        //        {
        //            finalPointFO.Add(item as PointFO);
        //        }
        //        else if (item is LineFO)
        //        {
        //            finalLineFO.Add(item as LineFO);
        //        }
        //    }

        //    List<FeatureObject> finalFO = new List<FeatureObject>();
        //    finalFO.AddRange(finalLineFO);
        //    finalFO.AddRange(finalPointFO);
        //    finalFO.AddRange(finalPolyFO);
        //    sw.Stop();
        //    Debug.WriteLine("多边形线生成多边形计算时间："+sw.ElapsedMilliseconds);
        //    sw.Restart();
        //    this.ResetFO(finalFO);
        //    sw.Stop();
        //    Debug.WriteLine("多边形绘制时间:"+sw.ElapsedMilliseconds);//因未更改添加刷新机制 故用时稍长
        //    #endregion
        //}

        #endregion

        /// <summary>
        /// 创建polygon间的关系
        /// </summary>
        /// <param name="counter"></param>
        /// <param name="polygonsWithRelates"></param>
        /// <param name="usedIndex"></param>
        void CreatePolygonRelate(int counter,ref Dictionary<int,PolygonRelates> polygonsWithRelates,ref List<int> usedIndex)
        {
            PolygonRelates currentPolyRelate = polygonsWithRelates[counter];

            foreach (int item in polygonsWithRelates.Keys)
            {
                if (counter != item)
                {
                    PolygonRelates comparePoly = polygonsWithRelates[item];
                    if (currentPolyRelate.PolygonNoHole.Contains(comparePoly.PolygonNoHole))
                    {
                        if (!usedIndex.Contains(item))
                            CreatePolygonRelate(item, ref polygonsWithRelates, ref usedIndex);

                        foreach (int itemContainIndex in polygonsWithRelates[item].ContainPolygonIndex)
                        {
                            currentPolyRelate.AlreadyContainedIndex.Add(itemContainIndex);
		                    if(currentPolyRelate.ContainPolygonIndex.Contains(itemContainIndex))
                            {
                                currentPolyRelate.ContainPolygonIndex.Remove(itemContainIndex);
                            }
                        }

                        if (!currentPolyRelate.AlreadyContainedIndex.Contains(item))
                            currentPolyRelate.ContainPolygonIndex.Add(item);
                    }
                    else if (comparePoly.PolygonNoHole.Contains(currentPolyRelate.PolygonNoHole))
                    {
                        //outerPoly.BeContainedPolygonIndex.Add(item);
                    }
                    else if (currentPolyRelate.PolygonNoHole.Intersects(comparePoly.PolygonNoHole))
                    {
                        currentPolyRelate.IntersectedPolygonIndex.Add(item);
                    }
                }

            }

            usedIndex.Add(counter);
        }




      


        /// <summary>
        /// 实现映射的主要函数，但是不能自己单独调用，需要由概念模型调用，此函数不能直接对外
        /// </summary>
        /// <param name="modflow"></param>
        internal void MapToModflow(List<double> stressPeriods, ModFlowData modflow)
        {

            //因为单层是可以mapto的，所以这里写对应的包选项，同时加入源汇的支持



            ////更新对应的源汇包
            //if (Setup.ScTypes[MAPSCType.WELL]==true)
            //{
            //    modflow.SourceSinks.Wells.Enabled = true;
                
            //}

            //if (Setup.ScTypes[MAPSCType.RIVER]==true)
            //{
            //    modflow.SourceSinks.Rivers.Enabled = true;
                
            //}


            //if (Setup.ScTypes[MAPSCType.DRAIN] == true)
            //{
            //    modflow.SourceSinks.Drains.Enabled = true;

            //}

            //if (Setup.ScTypes[MAPSCType.SPECIFIEDHEAD] == true)
            //{
            //    modflow.SourceSinks.SpecifiedHeads.Enabled = true;

            //}

            //if (Setup.ScTypes[MAPSCType.SEEPAGEFACE] == true)
            //{
            //    modflow.SourceSinks.Drains.Enabled = true;

            //}

            //if (Setup.ScTypes[MAPSCType.SPECIFIEDFLOW] == true)
            //{
            //    modflow.SourceSinks.Wells.Enabled = true;

            //}


            //if (Setup.ScTypes[MAPSCType.GENERALHEAD] == true)
            //{
            //    modflow.SourceSinks.GeneralHeads.Enabled = true;

            //}



            if (Setup.ArealTypes[MAPArealType.RECHARGERATE] == true)
            {

                modflow.SourceSinks.Recharges.Enabled = true;

            }

            if (Setup.ArealTypes[MAPArealType.MAXETRATE] == true || Setup.ArealTypes[MAPArealType.ETELEV] == true || Setup.ArealTypes[MAPArealType.ETEXTINCTIONDEPTH] == true)
            {


                modflow.SourceSinks.Evts.Enabled = true;

            }





            ///加入对应的源汇刷新选项



            foreach (FeatureObject item in _featureobjects)
            {

                item.MapToModFlow(stressPeriods,modflow,this._setup);







            }



            //if (this._setup.ScTypes[MAPSCType.RIVER]==true)
            //{
            //    modflow.SourceSinks.Rivers.CommitTempRivers(); 


                
            //}



        }


        internal void MapToMT3DMS(List<double> stressPeriods, HA.MT3DMS.DomainLayer.MT3DMSData data)
        {

            foreach (FeatureObject fo in this._featureobjects)
            {
                fo.MapToMT3dMS(stressPeriods, data,this.Setup);
                
            }


        
        }

        internal void OnSpeListChanged()
        {

            List<MT3DMS.DomainLayer.MTSpecies> lst = this._parentCM.Model.SpeList;

            List<string> lstName = new List<string>();
            foreach (MT3DMS.DomainLayer.MTSpecies item in lst)
            {

                lstName.Add(item.Name);
            }


            foreach (FeatureObject fo in this._featureobjects)
            {

                fo.OnSpeListChanged(lstName);


            }



        }


        //internal void OnNPeriodsChanged()
        //{

        //    int n = this._parentCM.Model.NPeriods;

        //    foreach (FeatureObject fo in this._featureobjects)
        //    {

        //        fo.OnNPeriodsChanged(n);


        //    }

 
        //}


        /// <summary>
        /// 构建所有fo的相交标志
        /// </summary>
        public void BuildFeatureObjectIJK(Polygon[,] polys,List<int[,]> ibound,Polygon polyGridFrame)
        {
            int layerFrom = this.Setup.LayerStart;
            int layerEnd = this.Setup.LayerEnd;


            bool isUseDefault = true;


            if (this.Setup.ScTypes[MAPSCType.LAYERRANGE] == true)
            {
                isUseDefault = false;

            }

            else
            {
                isUseDefault = true;
 
            }

            //循环所有实体，进行统一的关系映射

            foreach (FeatureObject item in this.Featureobjects)
            {

                item.BuildIJKList(polys,ibound,polyGridFrame,isUseDefault,layerFrom,layerEnd);
                
            }


 
        }


       

        public void Add(FeatureObject fo)
        {

            //加入一些默认的设置信息

            fo.LayerRange.FromLayer = this._setup.LayerStart;
            fo.LayerRange.ToLayer = this._setup.LayerEnd;


            this._featureobjects.Add(fo);

            if (this._parentCM != null)
            {
                if (this._parentCM.ParentMapData != null)
                {

                    this.ParentCM.ParentMapData.AskFOCollecionChanged(new FOCollecionChangedEventArgs(this.ParentCM, this, new List<FeatureObject>() { fo}, CollectionChangedType.ADD));


                }

            }




        }

        public FeatureObject GetFetureObjectFormPolyline(string polylineKey)
        {
            foreach (FeatureObject item in this._featureobjects)
            {
                if (item is PolygonFO)
                {
                    if ((item as PolygonFO).PolyKey == polylineKey)
                    {
                        return item;

                    }
                }

            }

            return null;
        }


        public FeatureObject GetFeatueObject(string id)
        {
            foreach (FeatureObject item in this._featureobjects)
            {
                if (item.Id == id)
                {
                    return item;

                }

            }



            return null;
        }

        public void DelectFOShape(string id)
        {
            FeatureObject fo = this.GetFeatueObject(id);

            if (fo == null)
                return;

            this._featureobjects.Remove(fo);
            //删除更新
            //if点更新线然后通过线更新面（涉及点连接）
            //if线更新点（删除与否）然后更新面（删除）
            //永远都不会直接对面进行操作
            //占位待添加=========================================================


            if (this._parentCM != null)
            {
                if (this._parentCM.ParentMapData != null)
                {
                    this.ParentCM.ParentMapData.AskFOCollecionChanged(new FOCollecionChangedEventArgs(this.ParentCM, this, new List<FeatureObject>() { fo }, CollectionChangedType.REMOVE));
                }

            }
        }


        /// <summary>
        /// 修改多个FO的图形部分
        /// </summary>
        /// <param name="fo"></param>
        public void ModifyFOShape(List<string> ids)
        {
            List<FeatureObject> foes = new List<FeatureObject>();

            foreach (string item in ids)
            {
                foes.Add(this.GetFeatueObject(item));
            }

            if (this._parentCM != null)
            {
                if (this._parentCM.ParentMapData != null)
                {
                    this.ParentCM.ParentMapData.AskFOCollecionChanged(new FOCollecionChangedEventArgs(this.ParentCM, this, foes, CollectionChangedType.ITEMEDIT));
                }

            }

        }

        /// <summary>
        /// 修改单个FO的图形部分
        /// </summary>
        /// <param name="id"></param>
        public void ModifyFOShape(string id)
        {
            this.ModifyFOShape(new List<string>() { id });
        }

        

        public void Remove(FeatureObject fo)
        {
            List<string> ids=new List<string>();
            ids.Add(fo.Id);

            if (this._featureobjects.Contains(fo) == false) return;

            //删除线
            if (fo is LineFO)
            {               
                (fo as LineFO).UpdateForLineChanged(CollectionChangedType.REMOVE,ref ids);
            }

            //删除多边形
            if (fo is PolygonFO)
            {                
                (fo as PolygonFO).UpdateForPolygonFOChanged(CollectionChangedType.REMOVE);
            }
            

            //删除节点
            if (fo is NodeFO)
            {               
                (fo as NodeFO).UpdateForVertexChanged(CollectionChangedType.REMOVE,ref ids);
            }

            //统一删除
            List<FeatureObject> foes = new List<FeatureObject>();

            foreach (string item in ids)
            {
                FeatureObject f = this.GetFeatueObject(item);

                if (f != null)
                {
                    foes.Add(f);
                    this._featureobjects.Remove(f);
                }
                else
                {

                }
            }
            
           

            if (this._parentCM != null)
            {
                if (this._parentCM.ParentMapData != null)
                {
                    this.ParentCM.ParentMapData.AskFOCollecionChanged(new FOCollecionChangedEventArgs(this.ParentCM, this, foes, CollectionChangedType.REMOVE));
                }

            }

        }


        public void Remove(List<string> featureIds)
        {
            List<string> ids = new List<string>();

            foreach (string id in featureIds)
            {
                FeatureObject fo = this.GetFeatueObject(id);

                if (fo == null)
                    continue;
                if (ids.Contains(fo.Id) == false)
                {
                    ids.Add(fo.Id);
                }

                //删除线
                if (fo is LineFO)
                {
                    (fo as LineFO).UpdateForLineChanged(CollectionChangedType.REMOVE, ref ids);
                }

                //删除多边形
                else if (fo is PolygonFO)
                {
                    (fo as PolygonFO).UpdateForPolygonFOChanged(CollectionChangedType.REMOVE);
                }


                //删除节点
                else if (fo is NodeFO)
                {
                    (fo as NodeFO).UpdateForVertexChanged(CollectionChangedType.REMOVE, ref ids);
                }

            }
            //统一删除
            List<FeatureObject> foes = new List<FeatureObject>();

            foreach (string item in ids)
            {
                FeatureObject f = this.GetFeatueObject(item);
                if (f != null)
                {
                    foes.Add(f);
                    this._featureobjects.Remove(f);
                }
            }




            if (this._parentCM != null)
            {
                if (this._parentCM.ParentMapData != null)
                {
                    this.ParentCM.ParentMapData.AskFOCollecionChanged(new FOCollecionChangedEventArgs(this.ParentCM, this, foes, CollectionChangedType.REMOVE));
                }

            }

        }


        /// <summary>
        /// 重置所有
        /// </summary>
        /// <param name="featureobjects"></param>
        void ResetFO(List<FeatureObject> featureobjects)
        {
            this._featureobjects.Clear();
            this._featureobjects.AddRange(featureobjects);

            if (this._parentCM != null)
            {
                if (this._parentCM.ParentMapData != null)
                {

                    this.ParentCM.ParentMapData.AskFOCollecionChanged(new FOCollecionChangedEventArgs(this.ParentCM, this,new List<FeatureObject>(), CollectionChangedType.RESET));

                }
            }
        }


        /// <summary>
        /// 只改变fo的源汇类型以及数据信息，不改变坐标值等gis信息
        /// </summary>
        public void ResetFOSCTypes(List<FeatureObject> featureobjects)
        {
            this._featureobjects.Clear();

            this._featureobjects.AddRange(featureobjects);
            foreach (FeatureObject  item in this._featureobjects)
            {
                item.Parent = this;
                
            }

            //FeatureObject fo;
            //for (int i = 0; i < this._featureobjects.Count; i++)
            //{
            //    if ((fo = featureobjects.FirstOrDefault<FeatureObject>(h => h.Id == _featureobjects[i].Id)) != null)
            //    {
            //        _featureobjects[i].Drain = fo.Drain;
            //        _featureobjects[i].GeneralHead = fo.GeneralHead;
            //        _featureobjects[i].LayerRange.FromLayer = fo.LayerRange.FromLayer;
            //        _featureobjects[i].LayerRange.ToLayer = fo.LayerRange.ToLayer;
            //        _featureobjects[i].LayerRange.AutoAssignLayer = fo.LayerRange.AutoAssignLayer;
            //        _featureobjects[i].LayerRange.Enabled = fo.LayerRange.Enabled;
            //        _featureobjects[i].MassLoading = fo.MassLoading;
            //        _featureobjects[i].Name = fo.Name;
            //        _featureobjects[i].LstIJK = fo.LstIJK;
            //        _featureobjects[i].River = fo.River;
            //        _featureobjects[i].Seepage = fo.Seepage;
            //        _featureobjects[i].SpecConc = fo.SpecConc;
            //        _featureobjects[i].SpecifiedHead = fo.SpecifiedHead;
            //        _featureobjects[i].SelectedSCType = fo.SelectedSCType;

            //        if (_featureobjects[i] is PointFO)
            //        {
            //            PointFO pf = (PointFO)_featureobjects[i];

            //            pf.RefinePoint = (fo as PointFO).RefinePoint;
            //            pf.Well = (fo as PointFO).Well;
            //        }
            //        else if (_featureobjects[i] is LineFO)
            //        {
            //            LineFO lf = (LineFO)_featureobjects[i];
                        
            //            lf.Barrier = (fo as LineFO).Barrier;
            //            lf.SpecifiedFlow = (fo as LineFO).SpecifiedFlow;
            //        }
            //        else if (_featureobjects[i] is PolygonFO)
            //        {
            //            PolygonFO pf = (PolygonFO)_featureobjects[i];

            //            pf.ArealPropertyData.Bulkdensity = (fo as PolygonFO).ArealPropertyData.Bulkdensity;
            //            pf.ArealPropertyData.EtExtDepth = (fo as PolygonFO).ArealPropertyData.EtExtDepth;
            //            pf.ArealPropertyData.EtRate = (fo as PolygonFO).ArealPropertyData.EtRate;
            //            pf.ArealPropertyData.GridBotElev = (fo as PolygonFO).ArealPropertyData.GridBotElev;
            //            pf.ArealPropertyData.GridTopElev = (fo as PolygonFO).ArealPropertyData.GridTopElev;
            //            pf.ArealPropertyData.Hani = (fo as PolygonFO).ArealPropertyData.Hani;
            //            pf.ArealPropertyData.Hk = (fo as PolygonFO).ArealPropertyData.Hk;
            //            pf.ArealPropertyData.Immobileporosity = (fo as PolygonFO).ArealPropertyData.Immobileporosity;
            //            pf.ArealPropertyData.Leakance = (fo as PolygonFO).ArealPropertyData.Leakance;
            //            pf.ArealPropertyData.Longdispersity = (fo as PolygonFO).ArealPropertyData.Longdispersity;
            //            pf.ArealPropertyData.MaxETRate = (fo as PolygonFO).ArealPropertyData.MaxETRate;
            //            pf.ArealPropertyData.Porosity = (fo as PolygonFO).ArealPropertyData.Porosity;
            //            pf.ArealPropertyData.PrimaryStorage = (fo as PolygonFO).ArealPropertyData.PrimaryStorage;
            //            pf.ArealPropertyData.RechargeRate = (fo as PolygonFO).ArealPropertyData.RechargeRate;
            //            pf.ArealPropertyData.SecondStorage = (fo as PolygonFO).ArealPropertyData.SecondStorage;
            //            pf.ArealPropertyData.SpecStorage = (fo as PolygonFO).ArealPropertyData.SpecStorage;
            //            pf.ArealPropertyData.SpecYield = (fo as PolygonFO).ArealPropertyData.SpecYield;
            //            pf.ArealPropertyData.Startingconcentration = (fo as PolygonFO).ArealPropertyData.Startingconcentration;
            //            pf.ArealPropertyData.Transmissity = (fo as PolygonFO).ArealPropertyData.Transmissity;
            //            pf.ArealPropertyData.Vani = (fo as PolygonFO).ArealPropertyData.Vani;
            //            pf.ArealPropertyData.Vk = (fo as PolygonFO).ArealPropertyData.Vk;
            //            pf.ArealPropertyData.WetdryFlag = (fo as PolygonFO).ArealPropertyData.WetdryFlag;
            //            pf.MapColor = (fo as PolygonFO).MapColor;
            //            pf.SpecifiedFlow = (fo as PolygonFO).SpecifiedFlow;
            //        }
            //    }
            //}

            if (this._parentCM != null)
            {
                if (this._parentCM.ParentMapData != null)
                {

                    this.ParentCM.ParentMapData.AskFOCollecionChanged(new FOCollecionChangedEventArgs(this.ParentCM, this, new List<FeatureObject>(), CollectionChangedType.MODIFYDATATYPES));

                }
            }
 
        }

        /// <summary>
        /// 将一个Node转换成Vertex
        /// </summary>
        /// <param name="id"></param>
        private void NodeToVertex(string id)
        {
            List<string> deleteIds = new List<string>();

            FeatureObject fo = this.GetFeatueObject(id);

            if (!(fo is NodeFO)) return;

            NodeFO node = fo as NodeFO;

            if (node.RelationLines.Count > 2) return;
            if (node.RelationLines.Count < 2) return;

            //如果这个节点连着两条线，但是其中一条线首尾点相连，则也不能进行合并
            if (node.RelationLines[0].VertexStart.Equals(node.RelationLines[0].VertexEnd)) return;
            if (node.RelationLines[1].VertexStart.Equals(node.RelationLines[1].VertexEnd)) return;


            //修正线1的坐标，将线2的坐标添加到线1，之后更新线2对应的多边形信息，删除线2即可
            List<HCoordinate> coorLst = new List<HCoordinate>();
            LineFO line1 = node.RelationLines[0];
            LineFO line2=node .RelationLines [1];

            bool line1Dir1 = true;
            bool line2Dir1 = true;


            if (line1.VertexEnd.Id == line2.VertexEnd.Id)
                line2Dir1 = false;
            else if (line1.VertexStart.Id == line2.VertexEnd.Id)
            {
                line1Dir1 = false;
                line2Dir1 = false;
            }
            else if (line1.VertexStart.Id == line2.VertexStart.Id)
                line1Dir1 = false;


            if (line1.VertexStart.Node.Equals(node))
            {
                if (line2 .VertexStart .Node .Equals (node ))
                {
                    List<HCoordinate> temCoors = new List<HCoordinate>();
                    temCoors.AddRange(line2.Coords.ToArray());
                    temCoors.Reverse();
                    coorLst.AddRange(temCoors.ToArray());
                    line1.VertexStart = line2.VertexEnd;
                    if (line1.VertexStart.Node.RelationLines.Contains(line1) == false)
                    {
                        line1.VertexStart.Node.RelationLines.Add(line1);
                    }
                }
                else 
                {
                    coorLst.AddRange(line2.Coords.ToArray());
                    line1.VertexStart = line2.VertexStart;
                    if (line1.VertexStart.Node.RelationLines.Contains(line1) == false)
                    {
                        line1.VertexStart.Node.RelationLines.Add(line1);
                    }
                }

                coorLst.Add(node.Position);

                line1.Coords.InsertRange(0,coorLst.ToArray());
            }
            else
            {
                coorLst.Add(node.Position);
                if (line2.VertexStart.Node.Equals(node))
                {
                    coorLst.AddRange(line2.Coords.ToArray());
                    
                    line1.VertexEnd = line2.VertexEnd;
                    if (line1.VertexEnd.Node.RelationLines.Contains(line1) == false)
                    {
                        line1.VertexEnd.Node.RelationLines.Add(line1);
                    }
                }
                else
                {
                    List<HCoordinate> temCoors = new List<HCoordinate>();
                    temCoors.AddRange(line2.Coords.ToArray());
                    temCoors.Reverse();
                    coorLst.AddRange(temCoors.ToArray());
                    line1.VertexEnd = line2.VertexStart;
                    if (line1.VertexEnd.Node.RelationLines.Contains(line1) == false)
                    {
                        line1.VertexEnd.Node.RelationLines.Add(line1);
                    }
                }
                line1.Coords.AddRange(coorLst.ToArray());
            }

            BCType bc = line1.GetCurrentBCType();
            if (bc != null)
            {
                BCType line2Type;
                if ((line2Type = line2.GetCurrentBCType()) != null && line2Type.GetType() == bc.GetType())
                {
                    if (bc is BCRiver)
                    {
                        BCRiver river = bc as BCRiver;
                        if (line1Dir1)
                        {
                            river.EndStage = line2Dir1 ? (line2Type as BCRiver).EndStage : (line2Type as BCRiver).StartStage;
                            river.EndElevation = line2Dir1 ? (line2Type as BCRiver).EndElevation : (line2Type as BCRiver).StartElevation;
                        }
                        else
                        {
                            river.StartStage = line2Dir1 ? (line2Type as BCRiver).EndStage : (line2Type as BCRiver).StartStage;
                            river.StartElevation = line2Dir1 ? (line2Type as BCRiver).EndElevation : (line2Type as BCRiver).StartElevation;
                        }
                    }
                    else if (bc is BCDrain)
                    {
                        BCDrain river = bc as BCDrain;
                        if (line1Dir1)
                            river.EndElevation = line2Dir1 ? (line2Type as BCDrain).EndElevation : (line2Type as BCDrain).StartElevation;
                        else
                            river.StartElevation = line2Dir1 ? (line2Type as BCDrain).EndElevation : (line2Type as BCDrain).StartElevation;
                    }
                    else if (bc is BCGeneralHead)
                    {
                        BCGeneralHead river = bc as BCGeneralHead;
                        if (line1Dir1)
                            river.EndHead = line2Dir1 ? (line2Type as BCGeneralHead).EndHead : (line2Type as BCGeneralHead).StartHead;
                        else
                            river.StartHead = line2Dir1 ? (line2Type as BCGeneralHead).EndHead : (line2Type as BCGeneralHead).StartHead;
                    }
                    else if (bc is BCSeepageFace)
                    {
                        BCSeepageFace river = bc as BCSeepageFace;
                        if (line1Dir1)
                            river.ElevOffSetEnd = line2Dir1 ? (line2Type as BCSeepageFace).ElevOffSetEnd : (line2Type as BCSeepageFace).ElevOffSetStart;
                        else
                            river.ElevOffSetStart = line2Dir1 ? (line2Type as BCSeepageFace).ElevOffSetEnd : (line2Type as BCSeepageFace).ElevOffSetStart;
                    }
                    else if (bc is BCSpecifiedHead)
                    {
                        BCSpecifiedHead river = bc as BCSpecifiedHead;
                        if (line1Dir1)
                            river.StageEnd = line2Dir1 ? (line2Type as BCSpecifiedHead).StageEnd : (line2Type as BCSpecifiedHead).StageStart;
                        else
                            river.StageStart = line2Dir1 ? (line2Type as BCSpecifiedHead).StageEnd : (line2Type as BCSpecifiedHead).StageStart;
                    }
                }
                else
                {
                    if (bc is BCRiver)
                    {
                        BCRiver river = bc as BCRiver;
                        if (line1Dir1)
                        {
                            river.EndStage = 0;
                            river.EndElevation = 0;
                        }
                        else
                        {
                            river.StartStage = 0;
                            river.StartElevation = 0;
                        }
                    }
                    else if (bc is BCDrain)
                    {
                        BCDrain river = bc as BCDrain;
                        if (line1Dir1)
                            river.EndElevation = 0;
                        else
                            river.StartElevation = 0;
                    }
                    else if (bc is BCGeneralHead)
                    {
                        BCGeneralHead river = bc as BCGeneralHead;
                        if (line1Dir1)
                            river.EndHead = 0;
                        else
                            river.StartHead = 0;
                    }
                    else if (bc is BCSeepageFace)
                    {
                        BCSeepageFace river = bc as BCSeepageFace;
                        if (line1Dir1)
                            river.ElevOffSetEnd = 0;
                        else
                            river.ElevOffSetStart = 0;
                    }
                    else if (bc is BCSpecifiedHead)
                    {
                        BCSpecifiedHead river = bc as BCSpecifiedHead;
                        if (line1Dir1)
                            river.StageEnd = 0;
                        else
                            river.StageStart = 0;
                    }
                }
            }

            //更新线2对应的多边形信息
            line1.UpdateForLineChanged(CollectionChangedType.ITEMEDIT, new List<LineFO>() { line2 }, false);

            node.RelationLines.Clear();

            deleteIds.Add(node.Id);
            deleteIds.Add(line2.Id);

            this.ModifyFOShape(line1.Id);
            this.Remove(deleteIds);


        }

        public void NodeToVertex(List<string> nodeIds)
        {
            foreach (string id in nodeIds)
            {
                this.NodeToVertex(id);
            }

        }



        #endregion



        #region 内部方法

        /// <summary>
        /// 取得有效单元  出错返回 null
        /// </summary>
        /// <param name="effectiveSign"></param>
        /// <param name="areaEffective"></param>
        /// <param name="layerRange"></param>
        /// <param name="surfacePointCoordinate"></param>
        /// <param name="boundGrid"></param>
        //private List<int[,]> GetSurfaceInPolygonEffectiveSign(List<int[,]> effectiveSign, List<int> layerRange, List<double[]> surfacePointCoordinate, HA.ModFlow.Domain.DomainLayer.GridData gridData)
        //{
        //    try
        //    {

        //        #region 首先是数据有效性的检验


        //        if (gridData == null || surfacePointCoordinate == null || layerRange == null || effectiveSign == null)
        //        {
        //            //effectiveSign = null;
        //            return null ;
        //        }
        //        ModFlow.Domain.DomainLayer.BoundGrid boundGrid = gridData.GetBoundGrid();
        //        if (boundGrid == null)
        //        {
        //            //effectiveSign = null;
        //            return null ;
        //        }
        //        if (effectiveSign.Count <= 0 || layerRange.Count <= 0 || surfacePointCoordinate.Count <= 0)
        //        {
        //            //effectiveSign = null;
        //            return null ;
        //        }

        //        for (int i = 0; i < layerRange.Count; i++)
        //        {
        //            if (layerRange[i] < 0)
        //            {
        //                //effectiveSign = null;
        //                //return;
        //                return null;
        //            }
        //        }
        //        for (int i = 0; i < surfacePointCoordinate.Count; i++)
        //        {
        //            if (surfacePointCoordinate[i].GetLength(0) != 3)
        //            {
        //                //effectiveSign = null;
        //                //return;

        //                return null;
        //            }
        //        }

        //        #endregion




        //        #region 记录面的坐标信息

        //        List<double[]> surfaceCoor = new List<double[]>();

        //        for (int i = 0; i < surfacePointCoordinate.Count; i++)
        //        {

        //            double[] pointCoor = new double[3];//记录点的坐标
        //            pointCoor[0] = surfacePointCoordinate[i][0];
        //            pointCoor[1] = surfacePointCoordinate[i][1];
        //            pointCoor[2] = 0;//Gis内部处理时  和 Z无关  值考虑XY（空间点XYZ在XY平面上的投影，投影在单元格内，则空间点在单元格内）
        //            //pointCoor[2] = linePointCoordinate [i][2];

        //            surfaceCoor.Add(pointCoor);

        //        }


        //        #endregion


        //        #region 构成单元格的点的信息

        //        //取得第一层上表面的网格边框信息
        //        HA.ModFlow.Domain.DomainLayer.Point3D[,] layerBound = boundGrid.GetLayerBound(0);
        //        if (layerBound == null)
        //        {
        //            //effectiveSign = null;
        //            //return;
        //            return null;
        //        }

        //        int rowNum = layerBound.GetLength(0) - 1;
        //        int colNum = layerBound.GetLength(1) - 1;


        //        List<double[]> polygonPointCoor = new List<double[]>();//记录多边形的各个顶点的坐标值

        //        //只需要使用网格在XY平面上的投影就可以了  K=0
        //        //int layer = 0;

        //        double[] cellEdgePoint1;//存储4个顶点坐标值信息的数组
        //        double[] cellEdgePoint2;
        //        double[] cellEdgePoint3;
        //        double[] cellEdgePoint4;

        //        #endregion

        //        #region 得到各个单元格的面积

        //        double[] colLength = new double[colNum];
        //        double[] rowLength = new double[rowNum];

        //        for (int i = 0; i < gridData.ColCoords.Length - 1; i++)
        //        {
        //            colLength[i] = gridData.ColCoords[i + 1] - gridData.ColCoords[i];
        //        }
        //        int index = 0;
        //        for (int j = gridData.RowCoords.Length - 2; j > -1; j--)
        //        {
        //            rowLength[index] = gridData.RowCoords[j + 1] - gridData.RowCoords[j];
        //            index = index + 1;
        //        }


        //        double areaEffective = 0.0;


        //        #endregion


        //        #region 平移旋转相关信息   此处不需要了

        //        //因为主程序要求ModFlow.Domain.DomainLayer.BoundGrid boundGrid = gridData.GetBoundGrid()修改为平移旋转后的点信息

        //        double orgX = gridData.OrgX;
        //        double orgY = gridData.OrgY;

        //        double rotateZ = gridData.RotationZ;

        //        #endregion

        //        for (int rows = 0; rows < rowNum; rows++)
        //        {
        //            for (int cols = 0; cols < colNum; cols++)
        //            {

        //                //依次遍历各个多边形单元格，并寻找他的四个角点

        //                #region 取得相关数据




        //                polygonPointCoor.Clear();

        //                #region 取得4个角点的坐标  注意按照顺时针或者逆时针的顺序

        //                cellEdgePoint1 = new double[3];

        //                //HAMath.Point2D newPoint1 = HAMath.ComputeNew2DGridPoint.GetNewPoint2D (layerBound[rows, cols].X, layerBound[rows, cols].Y,orgX ,orgY ,rotateZ );

        //                //if (newPoint1 == null)
        //                //{
        //                //    continue;
        //                //}

        //                //cellEdgePoint1[0] = newPoint1.X;
        //                //cellEdgePoint1[1] = newPoint1.Y;


        //                cellEdgePoint1[0] = layerBound[rows, cols].X;
        //                cellEdgePoint1[1] = layerBound[rows, cols].Y;
        //                cellEdgePoint1[2] = 0;
        //                //cellEdgePoint1[2] = layerBound[rows, cols].Z;

        //                polygonPointCoor.Add(cellEdgePoint1);//第一个角点


        //                cellEdgePoint2 = new double[3];

        //                //HAMath.Point2D newPoint2 = HAMath.ComputeNew2DGridPoint.GetNewPoint2D(layerBound[rows, cols + 1].X, layerBound[rows, cols + 1].Y, orgX, orgY, rotateZ);

        //                //if (newPoint2 == null)
        //                //{
        //                //    continue;
        //                //}

        //                //cellEdgePoint2[0] = newPoint2.X;
        //                //cellEdgePoint2[1] = newPoint2.Y;

        //                cellEdgePoint2[0] = layerBound[rows, cols + 1].X;
        //                cellEdgePoint2[1] = layerBound[rows, cols + 1].Y;

        //                cellEdgePoint2[2] = 0;
        //                //cellEdgePoint2[2] = layerBound[rows, cols + 1].Z;

        //                polygonPointCoor.Add(cellEdgePoint2);//第二个角点


        //                cellEdgePoint3 = new double[3];


        //                //HAMath.Point2D newPoint3 = HAMath.ComputeNew2DGridPoint.GetNewPoint2D(layerBound[rows + 1, cols + 1].X, layerBound[rows + 1, cols + 1].Y, orgX, orgY, rotateZ);

        //                //if (newPoint3 == null)
        //                //{
        //                //    continue;
        //                //}

        //                //cellEdgePoint3[0] = newPoint3.X;
        //                //cellEdgePoint3[1] = newPoint3.Y;

        //                cellEdgePoint3[0] = layerBound[rows + 1, cols + 1].X;
        //                cellEdgePoint3[1] = layerBound[rows + 1, cols + 1].Y;

        //                cellEdgePoint3[2] = 0;
        //                //cellEdgePoint3[2] = layerBound[rows + 1, cols + 1].Z;


        //                polygonPointCoor.Add(cellEdgePoint3);//第三个角点


        //                cellEdgePoint4 = new double[3];


        //                //HAMath.Point2D newPoint4 = HAMath.ComputeNew2DGridPoint.GetNewPoint2D(layerBound[rows + 1, cols].X, layerBound[rows + 1, cols].Y, orgX, orgY, rotateZ);

        //                //if (newPoint4 == null)
        //                //{
        //                //    continue;
        //                //}

        //                //cellEdgePoint4[0] = newPoint4.X;
        //                //cellEdgePoint4[1] = newPoint4.Y;


        //                cellEdgePoint4[0] = layerBound[rows + 1, cols].X;
        //                cellEdgePoint4[1] = layerBound[rows + 1, cols].Y;


        //                cellEdgePoint4[2] = 0;
        //                //cellEdgePoint4[2] = layerBound[rows + 1, cols].Z;

        //                polygonPointCoor.Add(cellEdgePoint4);//第四个角点

        //                #endregion


        //                HAMath.IntersectPolygonResult intersectPolygonResult = HAMath.SurfaceInPolygonRegion.JudgePolygonIntersectionPolygon(surfaceCoor, polygonPointCoor);

        //                if (intersectPolygonResult.IsInPolygon == true)
        //                {
        //                    //暂时按照相交的面积大于等于单元格的一半面积的时候 认为有效

        //                    areaEffective = colLength[cols] * rowLength[rows] * 0.5;

        //                    if (intersectPolygonResult.ResultValue >= areaEffective)
        //                    {

        //                        //取得相交的单元格的 IJK 值  改变其有效性标志

        //                        for (int i = 0; i < layerRange.Count; i++)
        //                        {
        //                            //layerRange中数据从1开始

        //                            effectiveSign[layerRange[i] - 1][rows, cols] = 1;

        //                        }


        //                    }

        //                }

        //                #endregion

        //            }//内层for循环结束

        //        }//外层for循环结束



        //        return effectiveSign;

        //    }
        //    catch
        //    {
        //        //System.Windows.MessageBox.Show("GetSurfaceInPolygonEffectiveSign取得单元格有效性标记的过程出错！");

        //        //effectiveSign = null;

        //        return null ;
        //    }
        //}



        #endregion


        #region 内部类

        /// <summary>
        /// 多边形间的关系类
        /// 单向包含其他逻辑写起来快 故未添加双向包含逻辑 但没有双向包含逻辑运行快
        /// </summary>
        class PolygonRelates
        {
            public PolygonRelates(Polygon polyNoHole, string polygonId = "")
            {
                this._polygonId = polygonId;
                this._polygonNoHole = polyNoHole;
            }
            ////被其他包含
            //List<int> beContainedPolygonIndex = new List<int>();

            //public List<int> BeContainedPolygonIndex
            //{
            //    get { return beContainedPolygonIndex; }
            //    set { beContainedPolygonIndex = value; }
            //}

            string _polygonId = "";
            /// <summary>
            /// 与多边形线对应标志 为空则无对应的多边形线
            /// </summary>
            public string PolygonId
            {
                get { return _polygonId; }
                set { _polygonId = value; }
            }

            List<int> _alreadyContainedIndex = new List<int>();
            /// <summary>
            /// 已经被内部包含的
            /// </summary>
            public List<int> AlreadyContainedIndex
            {
                get { return _alreadyContainedIndex; }
                set { _alreadyContainedIndex = value; }
            }


            //包含其他
            List<int> containPolygonIndex = new List<int>();
            /// <summary>
            /// 包含其他
            /// </summary>
            public List<int> ContainPolygonIndex
            {
                get { return containPolygonIndex; }
                set { containPolygonIndex = value; }
            }
            //相交图形
            List<int> intersectedPolygonIndex = new List<int>();

            public List<int> IntersectedPolygonIndex
            {
                get { return intersectedPolygonIndex; }
                set { intersectedPolygonIndex = value; }
            }

            Polygon _polygonNoHole;

            public Polygon PolygonNoHole
            {
                get { return _polygonNoHole; }
                set { _polygonNoHole = value; }
            }

        }


        #endregion

    }
}
